package cn.modfun.common.file;



import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * Ini 文件读写工具类
 * 
 * @author 
 * @version create on 2017年11月03日,last modify at 2017年11月07日
 */
public class IniUtils {
	private static Charset CHARSET_DEFAULT = Charset.forName("UTF-8");
	
	/* 区块 */
	private Map<String, Section> sectionMap;
	
	//--构造函数
	
	public IniUtils() {
		sectionMap = new LinkedHashMap<>();
	}
	public IniUtils(InputStream inputStream) throws IOException{
		this(inputStream, CHARSET_DEFAULT);
	}
	public IniUtils(InputStream inputStream, Charset charset) throws IOException {
		this();
		if(charset == null) {
			charset = CHARSET_DEFAULT;
		}
		List<String> lines = readIOLines(inputStream, charset.toString());
		initByLines(lines);
	}
	public IniUtils(String filePath) throws IOException {
		this(filePath, CHARSET_DEFAULT);
	}
	public IniUtils(String filePath, Charset charset) throws IOException {
		this();
		if(charset == null) {
			charset = CHARSET_DEFAULT;
		}
		List<String> lines = readFileLines(filePath, charset);
		initByLines(lines);
	}
	public IniUtils(List<String> lines) {
		this();
		initByLines(lines);
	}
	
	
	//--取值
	/**
	 * 获取所有标签
	 * @return
	 */
	public List<String> getSectionList() {
		List<String> list = new ArrayList<>();
		Iterator<String> itor = sectionMap.keySet().iterator();
		while(itor.hasNext()) {
			list.add(itor.next());
		}
		return list;
	}
	/**
	 * 获取某个标签下所有键
	 * @param sectionKey
	 * @return
	 */
	public List<String> getKeyList(String sectionKey) {
		Section section = getMapValue(sectionMap, sectionKey);
		if(section == null) {
			return new ArrayList<>();
		} else {
			return section.keyList();
		}
	}
	/**
	 * 获取值
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public Optional<String> getValue(String sectionKey, String valueKey) {
		try {
			return Optional.ofNullable(section(sectionKey).value(valueKey).get());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return Optional.empty();
	}
	
	/**
	 * 获取值并转换为Integer类型
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public Optional<Integer> getIntValue(String sectionKey, String valueKey) {
		try {
			return Optional.ofNullable(section(sectionKey).value(valueKey).intValue());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return Optional.empty();
	}
	
	/**
	 * 获取值并转化为Long类型
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public Optional<Long> getLongValue(String sectionKey, String valueKey) {
		try {
			return Optional.ofNullable(section(sectionKey).value(valueKey).longValue());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return Optional.empty();
	}
	
	/**
	 * 获取值并转化为Float类型
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public Optional<Float> getFloatValue(String sectionKey, String valueKey) {
		try {
			return Optional.ofNullable(section(sectionKey).value(valueKey).floatValue());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return Optional.empty();
	}
	
	/**
	 * 获取值并转化为Double类型
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public Optional<Double> getDoubleValue(String sectionKey, String valueKey) {
		try {
			return Optional.ofNullable(section(sectionKey).value(valueKey).doubleValue());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 获取值并转化为Boolean类型
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public Optional<Boolean> getBooleanValue(String sectionKey, String valueKey) {
		try {
			return Optional.ofNullable(section(sectionKey).value(valueKey).booleanValue());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return Optional.empty();
	}
	
	/**
	 * 获取值并转化为Date类型
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public Optional<Date> getDateValue(String sectionKey, String valueKey) {
		try {
			return Optional.ofNullable(section(sectionKey).value(valueKey).dateValue());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return Optional.empty();
	}
	
	/**
	 * 通过标签名获取对应标签，不存在抛出异常
	 * @param section
	 * @return
	 */
	public Section section(String section) {
		Section result = getMapValue(sectionMap, section);
		if(result == null) {
			throw new RuntimeException(
					concatStr("section[", section, "] not found"));
		}
		return result;
	}
	
	//--修改
	/**
	 * 插入新section(标签),旧的同名标签会被顶替
	 * @param section
	 * @return
	 */
	public IniUtils addSection(Section section) {
		sectionMap.put(section.name, section);
		return this;
	}
	
	/**
	 * 替换原有的值,不存在会抛出异常
	 * @param sectionKey
	 * @param valueKey
	 * @param value
	 * @return
	 */
	public IniUtils update(String sectionKey, String valueKey, Object value) {
		section(sectionKey).put(valueKey, value);
		return this;
	}
	
	/**
	 * 不存在则新建，存在则替换
	 * @param sectionKey
	 * @param valueKey
	 * @param value
	 * @return
	 */
	public IniUtils addOrUpadate(String sectionKey, String valueKey, Object value) {
		Section section = getMapValue(sectionMap, sectionKey);
		if(section == null) {
			section = newSection(sectionKey);
			sectionMap.put(sectionKey, section);
		}
		section.put(valueKey, value);	//存在则覆盖，没有则插入
		return this;
	}
	
	/**
	 * 删除某个标签下的键
	 * @param sectionKey
	 * @param valueKey
	 * @return
	 */
	public IniUtils removeKey(String sectionKey, String valueKey) {
		Section section = getMapValue(sectionMap, sectionKey);
		if(section != null) {
			section.removeKey(valueKey);
		}
		return this;
	}
	
	/**
	 * 删除某个标签
	 * @param sectionKey
	 * @return
	 */
	public IniUtils removeSection(String sectionKey) {
		if(sectionMap.containsKey(sectionKey)) {
			sectionMap.remove(sectionKey);
		}
		return this;
	}
	
	//--builder
	/**
	 * 创建section(内部类只能这么创建)
	 * @param sectionKey
	 * @return
	 */
	public Section newSection(String sectionKey) {
		return new Section(sectionKey);
	}
	
	/**
	 * 创建section(内部类只能这么创建)
	 * @param sectionKey
	 * @param noteList
	 * @return
	 */
	public Section newSection(String sectionKey, List<String> noteList) {
		return new Section(sectionKey).noteList(noteList);
	}
	
	
	//--转化
	/**
	 * 转化为行列表
	 * @return
	 */
	public List<String> toLines() {
		List<String> lines = new ArrayList<>();
		if(sectionMap == null || sectionMap.isEmpty()) {
			return lines;
		}
		sectionMap.forEach((secKey,section)->{	//标签名，标签具体内容
			if(!isEmpty(section.noteList)) {
				section.noteList.forEach(noteLine->{	//标签前的注释
					lines.add("#"+noteLine);
				});
			}
			lines.add(concatStr('[', secKey, "]"));	//标签名
			if(!isEmpty(section.valueMap)) {
				section.valueMap.forEach((key, val)->{	//键值对
					if(!isEmpty(val.noteList)) {
						val.noteList.forEach(noteLine->{
							lines.add("#"+noteLine);
						});
					}
					lines.add(concatStr(key, "=", val));
				});
			}
			lines.add("");	//标签(模块之间隔出一行空行)
		});
		
		return lines;
	}
	
	/**
	 * 转化为行列表
	 * <p>
	 * 会在每个键前面加上标签名做区分
	 * </p>
	 * @return
	 */
	public List<String> toPropertiesLines() {
		List<String> lines = new ArrayList<>();
		if(sectionMap == null || sectionMap.isEmpty()) {
			return lines;
		}
		sectionMap.forEach((secKey,section)->{	//标签名，标签具体内容
			if(!isEmpty(section.noteList)) {
				section.noteList.forEach(noteLine->{	//标签前的注释
					lines.add("#"+noteLine);
				});
			}
			
			if(!isEmpty(section.valueMap)) {
				section.valueMap.forEach((key, val)->{	//键值对
					if(!isEmpty(val.noteList)) {
						val.noteList.forEach(noteLine->{
							lines.add("#"+noteLine);
						});
					}
					lines.add(concatStr(secKey, ".", key, "=", val));
				});
			}
			lines.add("");	//标签(模块之间隔出一行空行)
		});
		
		return lines;
	}
	
	
	/**
	 * 保存到文件
	 * @param filePath
	 * @param charset
	 * @throws IOException
	 */
	public void save(String filePath, Charset charset) throws IOException {
		writeFile(filePath, toLines(), charset.toString(), true);
	}
	
	/**
	 * 保存到文件
	 * @param filePath
	 * @param charset
	 * @throws IOException
	 */
	public void save(String filePath) throws IOException {
		writeFile(filePath, toLines(), CHARSET_DEFAULT.toString(), true);
	}
	
	/**
	 * 保存为properties文件
	 * @param filePath
	 * @throws IOException
	 */
	public void saveAsProperties(String filePath) throws IOException {
		writeFile(filePath, toPropertiesLines(), CHARSET_DEFAULT.toString(), true);
	}
	
	//--内部方法
	/**
	 * 通过内容行来初始化ini工具类对象
	 */
	private void initByLines(List<String> lines) {
		if(lines == null) {
			return;
		}
		
		List<String> noteList = new ArrayList<String>();
		Section sectionTmp = null;	//临时指针
		/*正则区*/
		Pattern p_note = Pattern.compile("^\\#(.*)$");				//注释
		Pattern p_section = Pattern.compile("^\\[([^\\]]+)\\]$");	//模块名
		Pattern p_pair = Pattern.compile("^([^=]+)=([^=]*)$");		//键值对(key一定要有，值可以没有，否则会被忽略)
		
		for (String line : lines) {
			line = line.trim();
			String note = findInStr(line, p_note, "$1");
			if(note != null) {	//这是一个注释行
				noteList.add(note.trim());
			}
			String sectionKey = findInStr(line, p_section, "$1");
			if(sectionKey != null) {	//这是一个模块行[xx] xx为模块名
				sectionKey = sectionKey.trim();
				sectionTmp = newSection(sectionKey, noteList);
				sectionMap.put(sectionKey, sectionTmp);
				noteList = new ArrayList<String>();	//清空note
			}
			String keyValue = findInStr(line, p_pair, "$1=$2");
			if(keyValue != null) {
				if(sectionTmp == null) {
					throw new RuntimeException("存在键值对没有归属模块");
				} else {
					String[] group = keyValue.split("=");
					sectionTmp.put(group[0].trim(), group.length>1?group[1].trim():"", noteList);
					noteList = new ArrayList<String>();	//清空note
				}
			}
			
		}
	}
	
	/**
	 * 内部区块类
	 * 
	 */
	public class Section {
		/* 区块关键字 */
		private String name;
		/* 区块注释 */
		private List<String> noteList;
		/*键值对*/
		private LinkedHashMap<String, Value> valueMap = new LinkedHashMap<>();

		public Section(String name) {
			this.name = name;
		}
		
		public String name() {
			return name;
		}
		
		private Section noteList(List<String> noteList) {
			this.noteList = noteList;
			return Section.this;
		}
		
		public List<String> noteList() {
			return noteList;
		}
		
		public List<String> keyList() {
			List<String> list = new ArrayList<>();
			Iterator<String> itor = valueMap.keySet().iterator();
			while(itor.hasNext()) {
				list.add(itor.next());
			}
			return list;
		}
		
		public Section put(String key, Object value) {
			if(value == null) {
				value = "";
			}
			valueMap.put(key, new Value(value.toString(), null));
			return Section.this;
		}
		public Section put(String key, String value, List<String> noteList) {
			valueMap.put(key, new Value(value, noteList));
			return Section.this;
		}
		public Section removeKey(String key) {
			if(valueMap.containsKey(key)) {
				valueMap.remove(key);
			}
			return Section.this;
		}
		public Map<String, Value> valueMap() {
			return valueMap;
		}
		
		/**
		 * 通过键获取对应的值，不存在抛出异常
		 * @param key
		 * @return
		 */
		public Value value(String key) {
			Value result = getMapValue(valueMap, key);
			if(result == null) {
				throw new RuntimeException(
						concatStr("key[", key,"] not found in section[", name, ']'));
			}
			return result;
		}
	}
	
	/**
	 * 内部值类
	 *
	 */
	public class Value {
		/*值*/
		private String value;
		/* 区块注释 */
		private List<String> noteList;
		
		public Value(String value) {
			this.value = value;
		}
		public Value(String value, List<String> noteList) {
			this.value = value;
			this.noteList = noteList;
		}
		
		public List<String> noteList() {
			return noteList;
		}
		
		public String get() {
			return value;
		}
		
		public IniUtils set(String value) {
			this.value = value;
			return IniUtils.this;
		}
		@Override
		public String toString() {
			return value;
		}
		public Integer intValue() {
			return toInteger(value);
		}
		public Long longValue() {
			return toLong(value);
		}
		public Float floatValue() {
			return toFloat(value);
		}
		public Double doubleValue() {
			return toDouble(value);
		}
		public Boolean booleanValue() {
			return toBoolean(value);
		}
		public Date dateValue() {
			return toDate(value);
		}
	}
	
	//--工具方法
	/**
     * 读取文件中的所有行
     * @param filePath
     * @param encoding
     * @return
     * @throws IOException
     */
    private static List<String> readFileLines(String filePath, Charset encoding) throws IOException {
    	try {
    		if(encoding == null) {
         		encoding = CHARSET_DEFAULT;
         	}
    		FileInputStream fis = new FileInputStream(filePath);
    		return readIOLines(fis, encoding.toString());
          } catch (FileNotFoundException ex) {
              throw new IOException(concatStr("文件[", filePath, "]不存在"), ex);
          } catch (IOException ex) {
              throw new IOException(concatStr("读取文件[",filePath,"]时发生错误!"), ex);
          } 
    }
    
    /**
	 * 读取所有行
	 * @param in
	 * @param encoding
	 * @return
	 * @throws IOException 
	 */
	private static List<String> readIOLines(InputStream in, String encoding) throws IOException {
		
		try{
			List<String> lines = new ArrayList<>();
			BufferedReader procin = new BufferedReader(new InputStreamReader(in, encoding));
			String s = null;
			while((s  = procin.readLine()) !=null){
				lines.add(s);
			}
			return lines;
		} catch(IOException ex) {
			throw ex;
		} finally {
			closeIO(in);
		}
	}
    
    /**
     * 将所有行写出到文件
     * @param filePath
     * @param lines
     * @param encoding
     * @param isOverride
     * @return
     * @throws IOException
     */
    public static File writeFile(String filePath, List<String> lines, String encoding, boolean isOverride) throws IOException {
    	String content = list2Str(lines, System.lineSeparator());
    	InputStream is = new ByteArrayInputStream(content.getBytes(encoding));
    	String sPath = extractFilePath(filePath);
        if (!pathExists(sPath)) {
            makeDir(sPath, true);
        }
        
        if (!isOverride && fileExists(filePath)) {
            return new File(filePath);
        }
        FileOutputStream out = null;
        try {
            File file = new File(filePath);
            out = new FileOutputStream(file);
            int byteCount = 0;
			byte[] bytes = new byte[1024];

			while ((byteCount = is.read(bytes)) != -1) {
				out.write(bytes, 0, byteCount);
			}
			out.flush();
            return file;
        } catch (IOException e) {
            e.printStackTrace();
            throw new IOException(concatStr("写入文件[",filePath,"]时发生错误!"), e);
        }  finally {
			closeIO(is,out);
		}
    }
    
    /**
	 * 关闭流(批量)
	 * @param closeables
	 */
	private static void closeIO(Closeable... closeables) {
		for (Closeable closeable : closeables) {
			closeIO(closeable);
		}
		
	}
	
	/**
	 * 关闭流
	 * @param closeable
	 */
	private static void closeIO(Closeable closeable) {
		try{
			if(closeable != null) {
				if(closeable instanceof OutputStream) {
					((OutputStream) closeable).flush();
				}
				closeable.close();
			}
		} catch(IOException ex) {
		}
		
	}
    
    /**
     * 检查指定文件的路径是否存在
     *
     * @param filePath 文件名称(含路径）
     * @return 若存在，则返回true；否则，返回false
     */
    private static boolean pathExists(String filePath) {
        String sPath = extractFilePath(filePath);
        return fileExists(sPath);
    }
    
    private static boolean fileExists(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }
    
    /**
     * 创建目录
     *
     * @param dirPath             目录名称
     * @param needCreateParentDir 如果父目录不存在，是否创建父目录
     * @return
     */
    private static boolean makeDir(String dirPath, boolean needCreateParentDir) {
        boolean zResult = false;
        File file = new File(dirPath);
        if (needCreateParentDir)
            zResult = file.mkdirs(); // 如果父目录不存在，则创建所有必需的父目录
        else
            zResult = file.mkdir(); // 如果父目录不存在，不做处理
        if (!zResult)
            zResult = file.exists();
        return zResult;
    }
    
    /**
     * 从文件的完整路径名（路径+文件名）中提取 路径（包括：Drive+Directroy )
     *
     * @param filePath 文件路径
     * @return
     */
    private static String extractFilePath(String filePath) {
        int nPos = filePath.lastIndexOf('/');
        if (nPos < 0) {
            nPos = filePath.lastIndexOf('\\');
        }

        return (nPos >= 0 ? filePath.substring(0, nPos + 1) : "");
    }
    
    /**
	 * 通过StringBuilder连接字符串
	 * 
	 * @param obj 	第一个值
	 * @param objs 	后续的值
	 * @return
	 */
	private static String concatStr(Object obj, Object... objs) {
		StringBuilder sb = new StringBuilder();
		sb.append(obj);
		if(objs != null) {
			for (Object item : objs) {
				sb.append(item);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 根据正则和替换表达式提取字符串中有用的部分以期望的格式返回(借鉴某爬虫app的github开源代码，这是真心好用)
	 * @param src
	 * @param pattern
	 * @param replacement
	 * @return
	 */
	private static String findInStr(String src, Pattern pattern, String replacement) {
		if(src != null && pattern != null) {
			Matcher matcher =  pattern.matcher(src);

			if (!matcher.find()) {	//没有匹配到则返回null

			} else if (matcher.groupCount() >= 1) {
				return getReplacement(matcher, replacement);
			}

		} else {	//如果元字符串为null或者正则表达式为null，返回源字符串
			return src;
		}
		return null;
	}
	
	private static String getReplacement(Matcher matcher, String replacement) {
		String temp = replacement;
		if (replacement != null) {
			for (int i = 1; i <= matcher.groupCount(); i++) {
				String replace = matcher.group(i);
				temp =  temp.replace("$" + i, (replace != null) ? replace : "");
			}
			return temp;
		} else {
			return matcher.group(1);
		}
	}
	
	/**
     * 获取map里key对应的值，不存在或null返回null
     * <p>
     * 例如：
     * </p>
     * 
     * <pre>
     * 		现有值为{a:1,b:2}的map
     *		getMapValue(map, a) = 1
     *		getMapValue(map, c) = null
     * </pre>
     * </p>
     * </p>
     * 
     * @param map 校验的类
     * @param key 键
     * @return 
     */
	private static <K,V,T>T getMapValue(Map<K, V> map, K key) {
		return get(map, key, null);
	}
	
	/**
     * 获取map里key对应的值，不存在或null返回defaultValue
     * <p>
     * 例如：
     * </p>
     * 
     * <pre>
     * 		现有值为{a:1,b:2}的map
     *		getMapValue(map, a, 2) = 1
     *		getMapValue(map, c, 2) = 2
     * </pre>
     * </p>
     * </p>
     * 
     * @param map 校验的类
     * @param key 键
     * @param defaultValue 默认值
     * @return 
     */
	@SuppressWarnings("unchecked")
	private static <K,V,T>T get(Map<K, V> map, K key, T defaultValue) {
		try {
			if(map != null && map.containsKey(key) && map.get(key) != null) {
				return (T) map.get(key);
			}
		}catch(Exception ex) {
		}
		return defaultValue;
	}
	
	/**
     * 拆分字符串获取list
     * <p>
     * 例如：
     * </p>
     * 
     * <pre>
     * 		ListUtils.of(new Integer[]{1,2,3});
     *		ListUtils.toString(list,",");
     *		得到的结果是1,2,3
     * </pre>
     * </p>
     * </p>
     */
	private static <T>String list2Str(List<T> list, String separator) {
		if(isEmpty(list)) {	//列表为空则返回空字符串
			return "";
		}
		StringBuilder sb = null;
		for (T item : list) {
			if(sb == null) {
				sb = new StringBuilder();
			} else if(separator != null) {
				sb.append(separator);
			}
			if(item != null) {
				sb.append(item.toString());
			} else {
				sb.append("null");
			}
		}
		return sb.toString();
	}
	
	private static <E>boolean isEmpty(Collection<E> collection) {
		if(collection == null || collection.isEmpty()) {
			return true;
		}
		return false;
	}
	
	private static <K,V>boolean isEmpty(Map<K, V> map) {
		if(map== null || map.isEmpty()) {
			return true;
		}
		return false;
	}
    
	
	/**
	 * 字符串转Double
	 * 
	 * @param src
	 * @return
	 */
	public static Double toDouble(String src) {
		try {
			return Double.parseDouble(src);
		} catch(Exception ex) {
			//转换失败
		}
		return null;
	}
	
	/**
	 * 字符串转Float
	 * 
	 * @param src
	 * @return
	 */
	public static Float toFloat(String src) {
		try {
			return Float.parseFloat(src);
		} catch(Exception ex) {
			//转换失败
		}
		return null;
	}
	
	/**
	 * 字符串转Integer
	 * 
	 * @param src
	 * @return
	 */
	public static Integer toInteger(String src) {
		try {
			return Integer.parseInt(src);
		} catch(Exception ex) {
			//转换失败
		}
		return null;
	}
	
	/**
	 * 字符串转Long
	 * @param src
	 * @return
	 */
	public static Long toLong(String src) {
		try {
			return Long.parseLong(src);
		} catch(Exception ex) {
			//转换失败
		}
		return null;
	}
	
	/**
	 * 字符串转Boolean
	 * <p>
	 * 	当字符串为"true"或者"1"时返回true
	 * 	当字符串为"false"或者"0"时返回false
	 * 	其余情况返回null
	 * </p>
	 * 
	 * @param src
	 * @return
	 */
	public static Boolean toBoolean(String src) {
		if(src != null) {
			if("true".equals(src) || "1".equals(src)) {
				return true;
			} else if("false".equals(src) || "0".equals(src)) {
				return false;
			}
		}
		
		return null;
	}
	
	/**
	 * 字符串转java.util.Date
	 * <p>
	 * 	支持四种格式
	 *	yyyy-MM-dd HH:mm:ss
	 *	yyyy-MM-dd HH:mm
	 * 	yyyy-MM-dd
	 * 	HH:mm:ss
	 * </p>
	 * 
	 * @param src
	 * @return
	 */
	public static java.util.Date toDate(String src) {
		try {
		if(src.matches("\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}")) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return sdf.parse(src);
		} else if(src.matches("\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}")) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			return sdf.parse(src);
		} else if(src.matches("\\d{4}-\\d{2}-\\d{2}")) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			return sdf.parse(src);
		} else if(src.matches("\\d{2}:\\d{2}:\\d{2}")) {
			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
			return sdf.parse(src);
		}
		} catch(Exception ex) {
			
		}
		return null;
	}
	
	/**
	 * 构建list
	 * <p>
	 * 	含一项
	 * </p>
	 * 
	 */
	public static <T>List<T> ofList(T item) {
		List<T> list = new ArrayList<>();
		list.add(item);
		return list;
	}
	
	/**
	 * 构建list
	 * <p>
	 * 	含两项
	 * </p>
	 * 
	 */
	public static <T>List<T> ofList(T item1, T item2) {
		List<T> list = ofList(item1);
		list.add(item2);
		return list;
	}
	
	public static void main(String[] args) throws IOException {
		IniUtils iu = new IniUtils();
		String path = "e:\\xx.ini";	//测试路径
		String propertiesPath = "e:\\xx.properties";	//测试路径
		iu.addSection(
				iu.newSection("真理")
					.noteList(null)
					.put("dev", "true", null))
		.addSection(
				iu.newSection("第二块")
					.put("first", "ww", ofList("我是注释"))
					.put("date", "2017-11-07", ofList("注释1","时间测试")))
					.save(path);
		IniUtils iu2 = new IniUtils(path);
		Date date = iu2.getDateValue("第二块", "date").get();
		System.out.println(date.getTime());
		
		iu2.update("真理", "dev", null)
			.addOrUpadate("第二块", "pi", 3.14)
			.addOrUpadate("test", "path", "e:\\a")
			.removeKey("第二块", "first").save(path);
		IniUtils iu3 = new IniUtils(path);
		System.out.println(iu3.getValue("真理", "dev").get());
		System.out.println(iu3.getValue("test", "path").get());
		System.out.println(iu3.getFloatValue("第二块", "pi").get());
		iu3.saveAsProperties(propertiesPath);
	}
}
